Java基础知识(四)
数组的定义及使用
基本概念
1.数组是一组变量的集合。数组属于引用数据类型。
2.数组的定义语法
(1)声明并开辟数组: 数组类型 数组名[] = new 数据类型[数组长度]
(2)分步完成:
// 声明数组
数组类型 数组名[] = null;
// 开辟数组
数组名 = new 数据类型 [数组长度]
3.数组开辟空间用,可利用数组名[下标|索引]
访问,下标从0开始。即长度为3的数组,下标值为0,1,2。下标超出范围,会出现数组越界异常(ArrayIndexOutOfBoundsException)。
4.数组是顺序结构且长度固定,可使用循环语句输出,可用数组名.length
获取数组长度。
public class Demo {
public static void main(String[] args) {
int datas[] = new int[3]; // 声明并开辟一个长度为3的数组
datas[0] = 1; // 为数组赋值,如不赋值,默认值为0
datas[1] = 2;
datas[2] = 3;
// for循环输出数组内容,datas.length获取数组长度
for (int x = 0; x < datas.length; x++) {
System.out.println(datas[x]);
}
}
}
5.数组属于**引用数据类型,**因此要进行内存分配。与保存对象的区别是对象的堆内存保存的是属性,数组的堆内存保存的是数据。
范例:分步完成
public class Demo {
public static void main(String[] args) {
int datas[] = null; // 声明数组
datas = new int[3]; // 开辟一个长度为3的数组
datas[0] = 1;
datas[1] = 2;
datas[2] = 3;
for (int x = 0; x < datas.length; x++) {
System.out.println(datas[x]);
}
}
}
6.数组可以进行引用传递。
public class Demo {
public static void main(String[] args) {
int datas[] = new int[3];
datas[0] = 1;
datas[1] = 2;
datas[2] = 3;
int temp[] = datas; // 引用传递
temp[0] = 99;
for (int x = 0; x < datas.length; x++) {
System.out.println(datas[x]); // 99 2 3
}
}
}
以上都是动态初始化数组
,即先开辟数组,再为数组赋值。
7.静态初始化数组:
在定义数组的同时为其赋值,语法:
(1)数组类型 数组名[] = {v1, v2 ,…,vn};
(2)数组类型 数组名[] = new 数据类型[] {v1, v2 ,…,vn};
范例:静态初始化数组
public class Demo {
public static void main(String[] args) {
int datas[] = new int[]{1, 2, 3}; // 静态初始化数组
for (int x = 0; x < datas.length; x++) {
System.out.println(datas[x]);
}
}
}
数组支持顺序数据访问,最大缺点是长度不能改变,因此在开发中不直接使用数组,但会使用数组的概念。
二维数组
1.一维数组就是一行数据:
索引 | 0 | 1 | 2 | 3 |
---|---|---|---|---|
数据 | 0 | 10 | 20 | 30 |
在一维数组中要查询一个数据,只要确定其索引即可。
二维数组,是一个数据表:
索引 | 0 | 1 | 2 | 3 |
---|---|---|---|---|
0 | 0 | 10 | 20 | 30 |
1 | 1 | 2 | 3 | 4 |
2 | 12 | 123 | 231 | 233 |
二维数组中要查询一个数据,需要定位列和行。二维数组中第一个[]
确定行,第二个[]
确定列。
2. 二维数组定义语法:
// 动态初始化:
数据类型 数组名称[][]=new 数据类型[行数][列数];
// 静态初始化:
数据类型 数组名称[][]=new 数据类型[][]{数组元素} ;
由此可以发现,二维数组就是将多个一维数组变为一个数组。
public class Demo {
public static void main(String[] args) {
int datas[][] = new int[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 外层循环控制数组的行
for (int x = 0; x < datas.length; x++) {
// 内层循环控制数组的列
for (int y = 0; y < datas[x].length ; y++) {
System.out.print(datas[x][y] + "\t");
}
System.out.println();
}
}
}
数组与方法的引用
1.方法的参数可以是数组:
public class Demo {
public static void main(String[] args) {
int datas[] = new int[]{1, 2, 3};
change(datas);
for (int x = 0; x < datas.length; x++) {
System.out.println(datas[x]);
}
}
public static void change(int temp[]) {
for (int x = 0; x < temp.length; x++) {
temp[x] *= 2; // 数组元素乘2保存
}
}
}
内存分析:
change()
执行完毕后,temp
不再指向datas
的堆内存,但change()
对datas
数据的修改被保存下来。
2.数组排序(冒泡排序):
数据的不同会造成排序次数的不同,但不论有多少数据,**总的排序次数不会超过数组长度。**只要排序次数达到数组长度的平方,就能排序成功。
public class ArrayDemo {
public static void main(String[] args) {
int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
for (int x = 0; x < datas.length; x++) {
for (int y = 0; y < datas.length - 1; y++) {
if (datas[y] > datas[x]) {
int t = datas[y];
datas[y] = datas[x];
datas[x] = t;
}
}
// 为更好地理解冒泡排序,输出每轮排序的结果
System.out.print("第" + (x + 1) + "次排序结果:");
print(datas);
System.out.println();
}
print(datas);
}
// 数组输出的方法
public static void print(int temp[]) {
for (int x = 0; x < temp.length; x++) {
System.out.print(temp[x] + " ");
}
}
}
建议:main()
是程序的起点,可以称为客户端。客户端的代码逻辑应简单,因此可将排序封装为方法。
public class ArrayDemo {
public static void main(String[] args) {
int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
sort(datas);
print(datas);
}
// 数组冒泡排序方法
public static void sort(int temp[]) {
for (int x = 0; x < temp.length; x++) {
for (int y = 0; y < temp.length - 1; y++) {
if (temp[y] > temp[x]) {
int t = temp[y];
temp[y] = temp[x];
temp[x] = t;
}
}
}
}
// 数组输出的方法
public static void print(int temp[]) {
for (int x = 0; x < temp.length; x++) {
System.out.print(temp[x] + " ");
}
}
}
3.数组转置
转置的概念(一维数组):·
原始数组 | 1,2,3,4,5,6,7,8 |
---|---|
转置后 | 8,7,6,5,4,3,2,1 |
转置操作的两个思路:
(1)定义一个新的数组,而后将原始数组按照倒序的方式插入到新的数组之中,随后改变原始数组的引用:
public class ArrayDemo {
public static void main(String[] args) {
int datas[] = new int[]{1,2,3,4,5,6,7,8};
datas = reverseOne(datas); // 让datas指向新数组,原始数据成为垃圾
}
// 数组逆序输出方法一
public static int [] reverseOne(int temp[]) {
// 定义新数组,长度与原始数组一致
int temps[] = new int[temp.length];
int foot = temp.length - 1; // 控制原始数组的索引
for (int x = 0; x < temps.length ; x++) {
temps[x] = temp[foot]; // 新数组按照原始数组倒序排列
foot --;
}
return temps;
}
}
上述代码实现转置,但产生了垃圾,不合理。
(2)利用算法,直接在数组上完成转置:
不论数组个数是奇数还是偶数,转换次数 = 数组长度 / 2
;
// 数组逆序输出方法
public static void reverse(int temp[]) {
int len = temp.length / 2;
int head = 0;
int tail = temp.length - 1;
for (int x = 0; x < len; x++) {
int t = temp[head];
temp[head] = temp[tail];
temp[tail] = t;
head++;
tail--;
}
}
4.行列数相等的二维数组转置:
public class Demo {
public static void main(String[] args) {
int data[][] = new int[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
reverse(data);
print(data);
}
// 专门实现数组的倒置操作
public static void reverse(int arr[][]) {
for (int x = 0; x < arr.length; x++) {
for (int y = x; y < arr.length; y++) {
if (x != y) { //行和列相同,进行交换
int temp = arr[x][y];
arr[x][y] = arr[y][x];
arr[y][x] = temp;
}
}
}
}
// 专门输出的方法
public static void print(int temp[][]) {
for (int x = 0; x < temp.length; x++) {
for (int y = 0; y < temp[x].length; y++) {
System.out.print(temp[x][y] + "、");
}
System.out.println();
}
System.out.println();
}
}
转置过程:
1[0][0] 2[0][1] 3[0][2]
4[1][0] 5[1][1] 6[1][2]
7[2][0] 8[2][1] 9[2][2]
第一次转换(x=0,y=x=0,循环3次)
·y的第一次循环(x==y)
1[0][0] 2[0][1] 3[0][2]
4[1][0] 5[1][1] 6[1][2]
7[2][0] 8[2][1] 9[2][2]
·y的第二次循环(x=0,y=1,进行交换)
1[0][0] 4[1][0] 3[0][2]
2[0][1] 5[1][1] 6[1][2]
7[2][0] 8[2][1] 9[2][2]
·y的第三次循环(x=0,y=2,进行交换)
1[0][0] 4[1][0] 7[2][0]
2[0][1] 5[1][1] 6[1][2]
3[0][2] 8[2][1] 9[2][2]
第二次转换(x=1,y=x=1,循环2次)
·y的第一次循环(x=1,y=1,不交换)
1[0][0] 4[1][0] 7[2][0]
2[0][1] 5[1][1] 6[1][2]
3[0][2] 8[2][1] 9[2][2]
·y的第二次循环(x=1,y=2,进行交换)
1[0][0] 4[1][0] 7[2][0]
2[0][1] 5[1][1] 8[2][1]
3[0][2] 6[1][2] 9[2][2]
第三次转换(x=2,y=x=2,循环11次)
·y的第二次循环(x=2,y=2,不交换)
1[0][0] 4[1][0] 7[2][0]
2[0][1] 5[1][1] 8[2][1]
3[0][2] 6[1][2] 9[2][2]
行列数不同的数组进行倒置,其思路是:数组的行数是原数组的列数,数组的列数是源数组的行数。需要改变原始数组的引用,会产生垃圾。
5.方法返回数组:
public class Demo {
public static void main(String[] args) {
int data[] = init(); // 接收数组
print(data);
System.out.println(init().length);
}
public static int[] init() {
return new int[]{1, 2, 3}; // 方法返回数组
}
public static void print(int temp[]) {
for (int x = 0; x < temp.length; x++) {
System.out.print(temp[x] + "、");
}
System.out.println();
}
}
操作数组的方法
1.Java对数组提供类库支持,下面介绍两个类库中的方法:
(1)数组拷贝:用一个数组的指定内容覆盖另一个数组指定内容。
语法:System.arraycopy(源数组名,源数组拷贝开始索引,目标数组名,目标数组开始拷贝索引,拷贝长度)
。
范例:数组拷贝
·数组A:1,2,3,4,5,6,7,8;
·数组B:11,22,33,44,55,66,77,88;
·拷贝后的数组B:11,22,5,6,7,66,77,88
public class Demo {
public static void main(String[] args) {
int dataA[] = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
int dataB[] = new int[]{11, 22, 33, 44, 55, 66, 77, 88};
System.arraycopy(dataA, 4, dataB, 2, 3);
ArrayDemo.print(dataB); // 调用之前代码中的数组输出方法
}
}
(2)数组排序:
语法:java.util.Arrays.sort(数组名)
public class Demo {
public static void main(String[] args) {
int dataA[] = new int[]{3, 2, 1, 4, 7, 0, 6, 5};
java.util.Arrays.sort(dataA);
ArrayDemo.print(dataA); // 调用之前代码中的数组输出方法
}
}
对象数组
1.对象数组是将多个对象交由数组处理。
2.对象数组的定义与一般数组一致:
范例: 动态初始化对象数组
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
// setter和getter方法略
public String getInfo() {
return "书名:" + title + ",价格:" + price;
}
}
public class Demo {
public static void main(String[] args) {
Book books[] = new Book[3];
books[0] = new Book("Java开发", 66.6);
books[1] = new Book("JSP", 6.6);
books[2] = new Book("C++", 16.6);
for (int x = 0; x < books.length; x++) {
System.out.println(books[x].getInfo());
//未实例化对象时,输出值全为null
}
}
}
范例:静态初始化对象数组:
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
// setter和getter方法略
public String getInfo() {
return "书名:" + title + ",价格:" + price;
}
}
public class Demo {
public static void main(String[] args) {
Book books[] = new Book[]{
new Book("Java开发", 66.6),
new Book("JSP", 6.6),
new Book("C++", 16.6)
};
for (int x = 0; x < books.length; x++) {
//未实例化对象时,输出值全为null
System.out.println(books[x].getInfo());
}
}
}
This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(四)/